package com.itheima.tlias.aop;

import com.alibaba.fastjson2.JSON;
import com.itheima.tlias.comment.MyComment;
import com.itheima.tlias.entity.OperateLog;
import com.itheima.tlias.mapper.LogPageMapper;
import com.itheima.tlias.utils.UserThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;

@Component
//@Aspect //当前类为切面类
@Slf4j
/*@Order(Ordered.HIGHEST_PRECEDENCE)//指定执行顺序，值越小，执行顺序越靠前*/
public class LogAspect {
    @Autowired
    HttpServletRequest httpServletRequest;
    @Autowired
    LogPageMapper logMapper;

    //环绕通知
    @Around("@annotation(mc)")
    public Object recordTime(ProceedingJoinPoint pjp, MyComment mc) throws Throwable {
       /*String token = httpServletRequest.getHeader("token");
        Claims claims = JwtUtils.parseJWT(token);
        Integer userid = claims.get("id", Integer.class);
        String username = claims.get("name", String.class);*/
        // 从当前线程中获取用户信息
        UserThreadLocal.UserInfo userInfo = UserThreadLocal.getUserInfo();
        Integer userid = userInfo.getId();
        String username = userInfo.getName();
        String desc = mc.desc();
        // 从pjp中获取类名、执行方法名、方法运行时参数、返回值
        LocalDateTime operateTime = LocalDateTime.now();
        Signature signature = pjp.getSignature();
        String className = signature.getDeclaringTypeName();
        String methodName = signature.getName();
        Object[] methodParams = pjp.getArgs();

        //记录方法执行开始时间
        long begin = System.currentTimeMillis();
        Object result = null;
        long end = 0;
        try {
            //执行原始方法
             result = pjp.proceed();
            //记录方法执行结束时间
             end = System.currentTimeMillis();
        } finally {
            OperateLog operateLog = OperateLog.builder()
                    .operateUser(userid)
                    .operateName(username)
                    .operateTime(operateTime)
                    .className(className)
                    .methodName(methodName)
                    .methodDesc(desc)
                    .methodParams(methodParams == null ? "" : JSON.toJSONString(methodParams))
                    .returnValue(result == null ? "" : JSON.toJSONString(result))
                    .costTime(end - begin)
                    .build();
            logMapper.insert(operateLog);
        }
        return result;
    }
}